package com.rainkaze.lifeharbor.tools.compass;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.rainkaze.lifeharbor.R;
import com.rainkaze.lifeharbor.databinding.ActivityToolCompassBinding;


public class CompassActivity extends AppCompatActivity implements SensorEventListener {

    private static final String TAG = CompassActivity.class.getSimpleName();
    private ActivityToolCompassBinding binding;

    private SensorManager sensorManager;
    private Sensor accelerometer;
    private Sensor magnetometer;

    private float[] gravityData = new float[3];
    private float[] geomagneticData = new float[3];
    private float[] orientationData = new float[3];
    private float[] rotationMatrix = new float[9];

    private float currentDegree = 0f;
    private float lastAnimatedDegree = 0f;
    private static final float SENSOR_FILTER_ALPHA = 0.1f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityToolCompassBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.toolbarCompass);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        }

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

        if (accelerometer == null || magnetometer == null) {
            binding.textViewDegrees.setText("设备不支持指南针");
            binding.textViewDirection.setVisibility(TextView.GONE);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (accelerometer != null && magnetometer != null) {
            sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
            sensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (accelerometer != null || magnetometer != null) {
            sensorManager.unregisterListener(this);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            applyLowPassFilter(event.values, gravityData, SENSOR_FILTER_ALPHA);
        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            applyLowPassFilter(event.values, geomagneticData, SENSOR_FILTER_ALPHA);
        }

        boolean success = SensorManager.getRotationMatrix(rotationMatrix, null, gravityData, geomagneticData);
        if (success) {
            SensorManager.getOrientation(rotationMatrix, orientationData);
            float azimuthInRadians = orientationData[0];
            float azimuthInDegrees = (float) Math.toDegrees(azimuthInRadians);

            currentDegree = (azimuthInDegrees + 360) % 360;

            updateUI();
        }
    }

    // 应用低通滤波器调整
    private void applyLowPassFilter(float[] input, float[] output, float alpha) {
        for (int i = 0; i < input.length; i++) {
            output[i] = alpha * input[i] + (1 - alpha) * output[i];
        }
    }

    private void updateUI() {
        // 调整目标角度，使得动画总是走最短路径
        float targetDegreeForAnimation = currentDegree;
        float diff = currentDegree - lastAnimatedDegree;

        if (Math.abs(diff) > 180) {
            if (diff > 0) {
                targetDegreeForAnimation -= 360;
            } else {
                targetDegreeForAnimation += 360;
            }
        }
        RotateAnimation rotateAnimation = new RotateAnimation(
                -lastAnimatedDegree,
                -targetDegreeForAnimation,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
        );
        rotateAnimation.setDuration(250);
        rotateAnimation.setFillAfter(true);
        binding.imageViewCompassNeedle.startAnimation(rotateAnimation);

        lastAnimatedDegree = currentDegree;

        binding.textViewDegrees.setText(String.format("%.0f°", currentDegree));
        binding.textViewDirection.setText(getDirectionString(currentDegree));
    }


    private String getDirectionString(float degrees) {
        String direction = "未知";
        if (degrees >= 337.5 || degrees < 22.5) {
            direction = "北";
        } else if (degrees >= 22.5 && degrees < 67.5) {
            direction = "东北";
        } else if (degrees >= 67.5 && degrees < 112.5) {
            direction = "东";
        } else if (degrees >= 112.5 && degrees < 157.5) {
            direction = "东南";
        } else if (degrees >= 157.5 && degrees < 202.5) {
            direction = "南";
        } else if (degrees >= 202.5 && degrees < 247.5) {
            direction = "西南";
        } else if (degrees >= 247.5 && degrees < 292.5) {
            direction = "西";
        } else if (degrees >= 292.5 && degrees < 337.5) {
            direction = "西北";
        }
        return direction;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            String accuracyStatus = "磁场传感器精度: ";
            switch (accuracy) {
                case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
                    accuracyStatus += "高";
                    break;
                case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
                    accuracyStatus += "中";
                    break;
                case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
                    accuracyStatus += "低 - 请校准设备 (晃动手机画8字)";
                    break;
                case SensorManager.SENSOR_STATUS_UNRELIABLE:
                    accuracyStatus += "不可靠 - 请远离磁场干扰并尝试校准";
                    break;
            }
            //调试用
            android.util.Log.d(TAG, accuracyStatus);
        }
    }

    @Override
    public boolean onSupportNavigateUp() {
        getOnBackPressedDispatcher().onBackPressed();
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        binding = null;
    }
}